import { RVOArray, IRVOArrayItem } from "./RVOArrayEx";

export interface IRvoPoolItem {
    inPool: boolean;
    reuse(): void;
    unuse(): void;
}

/**
 * 避障对象池
 */
export class RvoPool<T extends IRvoPoolItem & IRVOArrayItem> {
    private _pool: RVOArray<T> = null;
    private _maxSize: number = 0;
    private _clazz: new () => T = null;

    static recycleFromArray<T extends IRVOArrayItem & IRvoPoolItem>(array: RVOArray<T>, pool: RvoPool<T>) {
        for (let i = 0, len = array.length; i < len; i++) {
            pool.put(array.get(i));
        }
        array.length = 0;
    }

    constructor(clazz: new () => T, size: number = 0, maxSize: number = 1024) {
        this._pool = new RVOArray<T>(size);
        this._maxSize = maxSize;
        this._clazz = clazz;
        for (let i = 0; i < size; i++) {
            this._pool.set(i, new clazz());
        }
    }

    public get() {
        let result: T;
        if (this._pool.length) {
            result = this._pool.pop();
        } else {
            result = new this._clazz();
        }
        result.inPool = false;
        result.reuse();
        return result;
    }

    public put(object: T) {
        if (object.inPool) return;
        if (this._pool.length < this._maxSize) {
            object.unuse();
            object.inPool = true;
            this._pool.push(object);
        }
    }

    public clear() {
        this._pool.length = 0;
    }
}